package com.zjgsu.nftplatform.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.zjgsu.nftplatform.entity.Role;
import com.zjgsu.nftplatform.entity.UserRole;
import com.zjgsu.nftplatform.mapper.CommonMapper;
import com.zjgsu.nftplatform.mapper.RoleMapper;
import com.zjgsu.nftplatform.mapper.UserRoleMapper;
import com.zjgsu.nftplatform.service.LoginService;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * @author ahy231
 * @date 2021/7/26 18:25
 * @description
 */
@Service
public class LoginServiceImpl implements LoginService {

    private final CommonMapper commonMapper;
    private final RoleMapper roleMapper;
    private final UserRoleMapper userRoleMapper;
    private final RedisTemplate<String, Object> redisTemplate;

    public LoginServiceImpl(CommonMapper commonMapper, RoleMapper roleMapper, UserRoleMapper userRoleMapper, RedisTemplate<String, Object> redisTemplate) {
        this.commonMapper = commonMapper;
        this.roleMapper = roleMapper;
        this.userRoleMapper = userRoleMapper;
        this.redisTemplate = redisTemplate;
    }

    @Override
    @SuppressWarnings({"unchecked", "rawtypes"})
    public Set<String> getRolesByUserId(long userId) {
        // 处理临时用户
        if (userId < 0L) {
            return Collections.singleton("visitor");
        }

        Set<String> roles = null;
        // 从 redis 查
        if (Boolean.TRUE.equals(redisTemplate.hasKey(userId + ""))) {
            roles = (Set<String>) (Set) redisTemplate.opsForSet().members(userId + "");
        }
        // 从数据库查
        if (roles == null) {
            roles = new HashSet<>(commonMapper.getRolesByUserId(userId));
            Assert.notNull(roles, "数据库中查询不到 userId 为 " + userId + " 的用户对应的角色");
            redisTemplate.opsForSet().add(userId + "", roles.toArray());
            redisTemplate.expire(userId + "", 1, TimeUnit.HOURS); // 设置过期时间为 1 小时
        }
        return roles;
    }

    @Override
    public void insertRole(long userId, String role) {
        Long roleId = roleMapper.selectOne(new QueryWrapper<Role>().eq("name", role)).getId();
        Assert.isTrue(userRoleMapper.insert(UserRole.builder().userId(userId).roleId(roleId).build()) > 0, "更新用户角色失败");
    }
}

